let PENDING = 'pending';
let FULFILLED = 'fulfilled';
let REJECTED = 'rejected';

class MyPromise {

  // 私有属性
  #state = PENDING;
  #result = undefined;

  constructor(executor) {
    console.log(executor)

    const resolve = (data) => {
      this.#changeState(FULFILLED, data);
    };
    const reject = (reason) => {
      this.#changeState(REJECTED, reason);
    }

    // 捕获错误，然后reject
    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  #changeState(state, result) {
    // 状态已经改变过了，就不能再改变了
    if (this.#state !== PENDING) return;

    this.#state = state;
    this.#result = result;
  }
}

// 测试
const promise = new MyPromise((resolve, reject) => {
  resolve(1);
})
console.log(promise)

// mypromise + then

class MyPromiseThen {

  // 状态
  #state = PENDING;
  // 结果
  #result = undefined;
  // 回调函数数组
  #onFulfilledCallbacks = [];
  #onRejectedCallbacks = [];

  // 改变状态
  #changeState(state, result) {
    if (this.#state !== PENDING) return;
    this.#state = state;
    this.#result = result;

    // 状态改变了，就要执行then里面的回调函数了
    if (this.#state === FULFILLED) {
      this.#onFulfilledCallbacks.forEach((callback) => callback(this.#result))
    } else if (this.#state === REJECTED) {
      this.#onRejectedCallbacks.forEach(callback => callback(this.#result));
    }
  }

  constructor(executor) {
    const resolve = (data) => {
      this.#changeState(FULFILLED, data);
    }
    const reject = (reason) => {
      this.#changeState(REJECTED, reason);
    }

    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }

  // 当promise状态改变时，执行then里的回调函数，返回一个新promise
  then(onFulfilled, onRejected) {
    return new MyPromiseThen((resolve, reject) => {
      // 包装回调函数，支持链式调用
      const fulfilledCallback = (value) => {
        try {
          const result = onFulfilled ? onFulfilled(value) : value;
          resolve(result);
        } catch (err) {
          reject(err);
        }
      }
      const rejectedCallback = (reason) => {
        try {
          const result = onRejected ? onRejected(reason) : reason;
          reject(result);
        } catch (err) {
          reject(err);
        }
      };

      if (this.#state === FULFILLED) {
        fulfilledCallback(this.#result);
      } else if (this.#state === REJECTED) {
        rejectedCallback(this.#result);
      } else {
        this.#onFulfilledCallbacks.push(fulfilledCallback);
        this.#onRejectedCallbacks.push(rejectedCallback);
      }
    })
  }
}